package com.example.wzh.rxdemo;

import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.GridLayoutManager;

import com.example.wzh.rxdemo.databinding.FragmentBusinessBinding;
import com.example.wzh.rxdemo.rx.MyObserver;
import com.example.wzh.rxdemo.rx.RepeatAccordingResultTransformer;
import com.example.wzh.rxdemo.rx.RetryFunction;
import com.example.wzh.rxdemo.rx.ScheduleTransformer;
import com.wzh.advancelog.log.WzhLog;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;

import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableSource;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;

public class BusinessFragment extends Fragment {
    FragmentBusinessBinding binding;
    CompositeDisposable compositeDisposable = new CompositeDisposable();

    @Override
    public View onCreateView(
            @androidx.annotation.NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_business, container, false);
        return binding.getRoot();
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        view.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                NavHostFragment.findNavController(BusinessFragment.this)
                        .navigate(R.id.action_business_to_operator);
            }
        });
        initBusiness();

    }

    private List<String> businesses;

    private void initBusiness() {
        businesses = new ArrayList<>();
        businesses.add("超时重试");
        businesses.add("异常重试");
        businesses.add("获取到结果后轮询");
        BusinessAdapter adapter = new BusinessAdapter(businesses);
        binding.rcv.setLayoutManager(new GridLayoutManager(getContext(), 4));
        binding.rcv.setAdapter(adapter);
        binding.rcv.addItemDecoration(new RecyclerSpace(4, Color.GRAY, RecyclerSpace.STYLE_WITH_EDGE));
        adapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(View ItemView, int position) {
                performBusiness(businesses.get(position));
            }
        });
    }

    private void performBusiness(String s) {
        switch (s) {
            case "超时重试":
                performOutTimeHandle();
                break;
            case "异常重试":
                performErrorRetry();
                break;
            case "获取到结果后轮询":
                performPoll();
                break;
            default:
                break;
        }

    }


    private void performPoll() {
        Observable.just(0).map(new Function<Integer, Integer>() {
            int autoIncreaseInt = 0;

            @Override
            public Integer apply(Integer integer) throws Throwable {
                Thread.sleep(1000);
                return autoIncreaseInt++;
            }
        }).compose(new RepeatAccordingResultTransformer<>(new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer < 7;
            }
        })).compose(new ScheduleTransformer<>())
                .subscribe(new MyObserver<>(compositeDisposable));
    }

    /**
     * 异常重试
     */
    private void performErrorRetry() {
        Observable.just(1).flatMap(new Function<Integer, ObservableSource<?>>() {
            int retryCount = -1;

            @Override
            public ObservableSource<?> apply(Integer integer) {
                retryCount++;
                if (retryCount < 5) {
                    return Observable.error(new Exception("error" + (int) (Math.random() * 1000)));
                } else {
                    return Observable.just(integer);
                }
            }
        }).doOnSubscribe(new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) {
                WzhLog.i(LogTag.TAG_WZH, "onSubscribe");
            }
        }).doOnError(new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                //可以用doOnError打印原始的Observable报错信息
                WzhLog.i(LogTag.TAG_WZH, "发生异常：" + throwable.getMessage());
            }//打印原始报错信息的操作可能与具体业务类相关，无需过度封装进Transformer里面
        }).retryWhen(new RetryFunction())
                .compose(new ScheduleTransformer<>())
                .subscribe(new MyObserver<>(compositeDisposable));
    }

    /**
     * 超时重试
     */
    private void performOutTimeHandle() {
        Observable.timer(10, TimeUnit.SECONDS).timeout(5, TimeUnit.SECONDS).doOnSubscribe(new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) {
                WzhLog.i(LogTag.TAG_WZH, "onSubscribe");
            }
        }).doOnError(new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                //可以用doOnError打印原始的Observable报错信息
                WzhLog.i(LogTag.TAG_WZH, "发生异常：" + throwable.getMessage());
            }
        }).retryWhen(new RetryFunction())
                .compose(new ScheduleTransformer<>())
                .subscribe(new MyObserver<>(compositeDisposable));
    }

    @Override
    public void onDestroy() {
        compositeDisposable.dispose();
        super.onDestroy();
    }
}